package com.wsoft.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.constant.redis.HrPmRedisKeyConstant;
import com.wsoft.constant.redis.RedisKeyConstant;
import com.wsoft.core.annotation.GetRedisCache;
import com.wsoft.core.annotation.InitRedisCache;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.CommonOrgService;
import com.wsoft.core.service.RedisService;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.utils.PasswordGenerator;
import com.wsoft.core.vo.OrganizationVO;
import com.wsoft.service.IMemberCommonService;
import com.wsoft.system.dto.SysMenuNode;
import com.wsoft.system.entity.*;
import com.wsoft.system.mapper.SysMemberMapper;
import com.wsoft.system.query.member.MemberInsertQuery;
import com.wsoft.system.query.member.MemberListQuery;
import com.wsoft.system.query.member.MemberUpdateActiveQuery;
import com.wsoft.system.query.member.MemberUpdateQuery;
import com.wsoft.system.service.*;
import com.wsoft.utils.Sm3EncryptionUtil;
import com.wsoft.vo.SysMemberVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.wsoft.constant.redis.RedisKeyConstant.USER_INFO_CACHE;

/**
 * <p>
 * 员工表 服务实现类
 * </p>
 *
 * @author juiet
 * @since 2024年09月03日 10:35:18
 */
@Service
public class SysMemberServiceImpl extends ServiceImpl<SysMemberMapper, SysMemberEntity> implements ISysMemberService {

    @Resource
    private ISysMemberOrgRoleRelationService memberOrgRoleRelationService;
    @Resource
    private ISysRoleMenuRelationService roleMenuRelationService;
    @Resource
    private ISysMemberOrgPostRelationService memberOrgPostRelationService;
    @Resource
    private ISysAccountService accountService;
    @Resource
    private ISysMenuService menuService;
    @Resource
    private CommonOrgService commonOrgService;
    @Resource
    private RedisService redisService;
    @Resource
    private IMemberCommonService memberCommonService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    @InitRedisCache(type = RedisKeyConstant.MEMBER_ALL_CACHE,
    value = RedisKeyConstant.REDIS_NULL)
    public boolean register(MemberInsertQuery query) {
        //todo 唯一性校验
        SysMemberEntity convert = Convert.convert(SysMemberEntity.class, query);
        boolean b = save(convert);
        if (b){
            //新增人员组织关系
            if (convert.getCurOrgId()!=null){
                SysMemberOrgRoleRelationEntity orgRelation = new SysMemberOrgRoleRelationEntity();
                orgRelation.setMemberId(convert.getId());
                orgRelation.setOrgId(query.getCurOrgId());
                orgRelation.setRoleId(null);
                memberOrgRoleRelationService.save(orgRelation);
            }
            //新增人员岗位关系
            if (convert.getCurPostId()!=null){
                SysMemberOrgPostRelationEntity postRelation = new SysMemberOrgPostRelationEntity();
                postRelation.setMemberId(convert.getId());
                postRelation.setOrgId(query.getCurOrgId());
                postRelation.setPostId(query.getCurPostId());
                memberOrgPostRelationService.save(postRelation);
            }
            //初始化账号
            QueryWrapper<SysAccountEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysAccountEntity::getLoginName,query.getLoginName());
            if (accountService.count(queryWrapper)>0){
                Asserts.fail("[sys.account.exist]");
            }
            SysAccountEntity entity = new SysAccountEntity();
            entity.setMemberId(convert.getId());
            entity.setLoginName(query.getLoginName());
            entity.setLoginPw(Sm3EncryptionUtil.encrypt(PasswordGenerator.generateHighLevelPassword(10)));
            entity.setConfigLayout("default");
            entity.setConfigSkin("blue");
            entity.setConfigLocation("left");
            entity.setIsUsed(1);
            boolean save = accountService.save(entity);
            if (save){
                OrganizationVO orgInfo = commonOrgService.getOrgInfo(query.getCurOrgId());
                update(Wrappers
                        .lambdaUpdate(SysMemberEntity.class)
                        .set(SysMemberEntity::getAccountId, entity.getId())
                        .set(SysMemberEntity::getLoginOrgId, orgInfo.getOrgId())
                        .set(SysMemberEntity::getLoginOrgCode, orgInfo.getCode())
                        .set(SysMemberEntity::getLoginOrgName, orgInfo.getName())
                        .eq(SysMemberEntity::getId, convert.getId())
                );
            }
        }
        return b;
    }

    @Override
    @InitRedisCache(types = {RedisKeyConstant.MEMBER_CACHE, RedisKeyConstant.MEMBER_ROLE_CACHE, RedisKeyConstant.MEMBER_POST_CACHE,RedisKeyConstant.MEMBER_ALL_CACHE},
            values = {"id","id","id",RedisKeyConstant.REDIS_NULL})
    public boolean update(MemberUpdateQuery query) {
        SysMemberEntity convert = Convert.convert(SysMemberEntity.class, query);
        //原数据
        SysMemberEntity entity = getById(query.getId());
        boolean b = updateById(convert);
        if (b){
            //修改人员组织关系
            if(!query.getCurOrgId().equals(entity.getCurOrgId())){
                QueryWrapper<SysMemberOrgRoleRelationEntity> orgQuery =  new QueryWrapper<>();
                orgQuery.lambda().eq(SysMemberOrgRoleRelationEntity::getMemberId,convert.getId());
                List<SysMemberOrgRoleRelationEntity> list = memberOrgRoleRelationService.list(orgQuery);
                List<Long> orgList = list.stream().map(SysMemberOrgRoleRelationEntity::getOrgId).collect(Collectors.toList());
                if (!orgList.contains(convert.getCurOrgId())){
                    SysMemberOrgRoleRelationEntity orgRelation = new SysMemberOrgRoleRelationEntity();
                    orgRelation.setMemberId(convert.getId());
                    orgRelation.setOrgId(convert.getCurOrgId());
                    memberOrgRoleRelationService.save(orgRelation);
                }
            }
            //修改人员组织岗位关系
            if(!query.getCurPostId().equals(entity.getCurPostId())){
                QueryWrapper<SysMemberOrgPostRelationEntity> postQuery =  new QueryWrapper<>();
                postQuery.lambda().eq(SysMemberOrgPostRelationEntity::getMemberId,convert.getId());
                List<SysMemberOrgPostRelationEntity> list = memberOrgPostRelationService.list(postQuery);
                List<Long> postList = list.stream().map(SysMemberOrgPostRelationEntity::getPostId).collect(Collectors.toList());
                if (!postList.contains(convert.getCurPostId())){
                    SysMemberOrgPostRelationEntity postRelation = new SysMemberOrgPostRelationEntity();
                    postRelation.setMemberId(convert.getId());
                    postRelation.setOrgId(query.getCurOrgId());
                    postRelation.setPostId(query.getCurPostId());
                    memberOrgPostRelationService.save(postRelation);
                }
            }
        }
        return b;
    }

    @Override
    public boolean updateActiveInfo(MemberUpdateActiveQuery query) {
        SysMemberEntity convert = Convert.convert(SysMemberEntity.class, query);
        Long id = LoginUserUtil.getUserInfo().getLoginUserVO().getId();
        convert.setId(id);
        boolean b = updateById(convert);
        if (b){
            redisService.del(RedisKeyConstant.MEMBER_CACHE+id);
        }
        return b;
    }

    @Override
    @GetRedisCache(type = RedisKeyConstant.MEMBER_CACHE,
                   value = RedisKeyConstant.REDIS_SELF)
    public SysMemberVO getMember(Long id) {
        SysMemberEntity entity = getById(id);
        SysMemberVO convert = Convert.convert(SysMemberVO.class, entity);
        SysAccountEntity account = accountService.getById(entity.getAccountId());
        convert.setLoginName(account.getLoginName());
        return convert;
    }

    @Override
    @InitRedisCache(types = {RedisKeyConstant.MEMBER_CACHE, RedisKeyConstant.MEMBER_ROLE_CACHE, RedisKeyConstant.MEMBER_POST_CACHE,RedisKeyConstant.MEMBER_ALL_CACHE},
            values = {RedisKeyConstant.REDIS_SELF,RedisKeyConstant.REDIS_SELF,RedisKeyConstant.REDIS_SELF,RedisKeyConstant.REDIS_NULL})
    public boolean delete(Long id) {
        SysMemberVO member = getMember(id);
        boolean b = removeById(id);
        if (b){
            memberOrgPostRelationService.deleteByMemberId(id);
            accountService.removeById(member.getAccountId());
        }
        return b;
    }

    @Override
    public PageInfo<SysMemberEntity> pageList(MemberListQuery query) {

        QueryWrapper<SysMemberEntity> memberQuery = new QueryWrapper<>();
        if (query.getOrgId()!=null){
            List<Long> orgIds = commonOrgService.getChildOrg(query.getOrgId()).stream().map(OrganizationVO::getOrgId).collect(Collectors.toList());
            memberQuery.lambda().in(SysMemberEntity::getCurOrgId,orgIds);
        }
        //编号
        if (StrUtil.isNotBlank(query.getCode())) {
            memberQuery.lambda().eq(SysMemberEntity::getCode,query.getCode());
        }
        //姓名
        if (StrUtil.isNotBlank(query.getName())) {
            memberQuery.lambda().like(SysMemberEntity::getName,query.getName());
        }
        //手机号
        if (query.getPhone()!=null) {
            memberQuery.lambda().eq(SysMemberEntity::getPhone,query.getPhone());
        }
        //主任职组织
        if (query.getCurOrgId()!=null) {
            memberQuery.lambda().eq(SysMemberEntity::getCurOrgId,query.getCurOrgId());
        }
        //登入组织
        if (query.getLoginOrgId()!=null) {
            memberQuery.lambda().eq(SysMemberEntity::getLoginOrgId,query.getLoginOrgId());
        }
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
            return  PageInfo.of(list(memberQuery));
        }

    @Override
    public List<SysMenuNode> treeMenuListByRoleIds(List<Long> roleIds) {
        List<SysMenuEntity> menuList = new ArrayList<>();
        roleIds.forEach(e->{
            List<SysMenuEntity> list = roleMenuRelationService.getMenuListByRoleId(e);
            menuList.addAll(list);
        });
        List<SysMenuEntity> result = menuList.stream().filter(e -> e.getType().equals(0)).collect(Collectors.toList());
        return menuService.treeList(result);
    }

    @Override
    @GetRedisCache(type = RedisKeyConstant.MEMBER_ALL_CACHE,
            value = RedisKeyConstant.REDIS_NULL)
    public List<SysMemberEntity> listAll() {
        return list();
    }

    @Override
    public String resetPwd(Long memberId) {
        String pwd = PasswordGenerator.generateHighLevelPassword(10);
        String encrypt = Sm3EncryptionUtil.encrypt(pwd);
        QueryWrapper<SysAccountEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysAccountEntity::getMemberId, memberId);
        SysAccountEntity entity = accountService.getOne(queryWrapper);
        entity.setLoginPw(encrypt);
        boolean b = accountService.updateById(entity);
        if (b) {
            //更新缓存
            redisService.del(USER_INFO_CACHE + entity.getLoginName());
            memberCommonService.loadUserByUsername(entity.getLoginName());
            return pwd;
        }
        return null;
    }

    @Override
    public Integer addGrowthValue() {
        Long memberId = LoginUserUtil.getUserInfo().getLoginUserVO().getId();
        SysMemberEntity entity = getById(memberId);
        if (redisService.get(HrPmRedisKeyConstant.GROWTH_VALUE+memberId) == null){
            entity.setGrowthValue(entity.getGrowthValue()+1);
            boolean b = updateById(entity);
            if (b){
                // 1. 获取当前时间
                Date now = DateUtil.date();
                // 2. 计算下一个自然日零点时间
                Date nextMidnight = DateUtil.beginOfDay(DateUtil.offsetDay(now, 1));
                // 3. 计算时间差（毫秒）
                long timeDiffMillis = DateUtil.between(now, nextMidnight, DateUnit.MS);
                redisService.set(HrPmRedisKeyConstant.GROWTH_VALUE+memberId ,1,timeDiffMillis);
                redisService.del(RedisKeyConstant.MEMBER_CACHE+memberId);
            }
        }
        else {
            Asserts.fail("[sys.add.growthValue]");
        }
    return getMember(memberId).getGrowthValue();
    }

    @Override
    public List<SysMemberEntity> hrMemberList(List<Long> memberIds, String name,String code,String phone)  {
        QueryWrapper<SysMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(CollUtil.isNotEmpty(memberIds),SysMemberEntity::getId,memberIds)
                .like(StrUtil.isNotBlank(name),SysMemberEntity::getName,name)
                .like(StrUtil.isNotBlank(code),SysMemberEntity::getCode,code)
                .like(StrUtil.isNotBlank(phone),SysMemberEntity::getPhone,phone)
        ;
        return list(queryWrapper);
    }
}
